package com.moorror.codegenvel.common.table;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBoxTableRenderer;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.ui.BooleanTableCellEditor;
import com.intellij.ui.BooleanTableCellRenderer;
import com.intellij.ui.treeStructure.treetable.TreeTableModel;
import com.intellij.util.ui.ColumnInfo;
import com.moorror.codegenvel.common.utils.JacksonUtils;
import org.jdesktop.swingx.treetable.DefaultMutableTreeTableNode;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

/**
 * @Author jiyanghuang
 * @Date 2022/8/3 23:32
 */
public class TableColumnInfo extends ColumnInfo {

    private String key;

    /**
     * 列描述
     */
    private ColumnDesc columnDesc;

    private static final TableCellRenderer MR_TABLE_CELL_RENDERER = new MRTableCellRenderer();
    private ComboBoxTableRenderer comboBoxTableRenderer;
    private BooleanTableCellRenderer booleanTableCellRenderer;
    private static final MongoValueCellEditor defaultEditor = new MongoValueCellEditor();
    private static final DefaultCellEditor defaultEditorV = new DefaultCellEditor(new JTextField());



    private final CellEditorText defaultJsonEditor;
    private final CellEditorTextV2 defaultJsonEditorV2;
    private TableCellEditor createComboBoxEditor;
    private BooleanTableCellEditor booleanTableCellEditor;
    private CellEditorMultiSelect cellEditorMultiSelect;

    private Project project;

    private boolean cellEditable;

    /**
     *
     * @param columnNames 每一列描述
     * @param items 数据List
     */
    public TableColumnInfo(@NlsContexts.ColumnName String name, Project project, boolean cellEditable, ColumnDesc columnDesc) {
        super(columnDesc.getNameShow());
        this.key = name;
        this.project = project;
        this.cellEditable = cellEditable;
        defaultJsonEditor = new CellEditorText(project);
        defaultJsonEditorV2 = new CellEditorTextV2(project);
        this.columnDesc = columnDesc;
    }

    @Override
    public Class<?> getColumnClass() {
        if(columnDesc.isColumnTree()){
            return TreeTableModel.class;
        }
        return super.getColumnClass();
    }

    /**
     * 获取到的是每一个方格的描述
     * @param o List 中的一个元素，对于封装而言就是 TreeLineWrap
     * @return 返回List 中的一个元素，取出该元素中该列的值，这里就是每个方格的描述对象 ColumnDesc
     */
    @Nullable
    @Override
    public Object valueOf(Object o) {
        if(o instanceof TreeLineWrap){
            TreeLineWrap treeLineWrap = (TreeLineWrap)o;
            return treeLineWrap.getCm().get(key);
        }else if(o instanceof DefaultMutableTreeTableNode){
            DefaultMutableTreeTableNode treeNode = (DefaultMutableTreeTableNode)o;
            if(null != treeNode.getUserObject() && treeNode.getUserObject() instanceof TreeLineWrap){
                TreeLineWrap treeLineWrap = (TreeLineWrap)treeNode.getUserObject();
                return treeLineWrap.getCm().get(key);
            }
        }
        return "empty";
    }

    /**
     * 每一个方格怎么渲染，所以传的对象是方格描述对象
     * @param o 方格中的对象，这里可以路由，根据传的对象决定渲染对象
     * @return
     */
    @Override
    public @Nullable TableCellRenderer getRenderer(Object o) {
        if(null != columnDesc.getColumnValueEnum()){
            if(ColumnValueEnum.SELECT.equals(columnDesc.getColumnValueEnum())){
                if(null == comboBoxTableRenderer){
                    comboBoxTableRenderer = new ComboBoxTableRenderer<>(columnDesc.getOptions().toArray(new String[0]));
                }
                return MR_TABLE_CELL_RENDERER;
            }else if(ColumnValueEnum.CHECKBOX.equals(columnDesc.getColumnValueEnum())){
                if(null == booleanTableCellRenderer){
                    booleanTableCellRenderer = new MRRenderBooleanTableCellRenderer();
                }
                return booleanTableCellRenderer;
            }
        }
        /**
         * 如果是树形，则需要区分哪个是treeColumn,哪个普通的column
         * 如果是 treeColumn则返回null,采用默认的实现，最终走到
         * @see com.moorror.codegenvel.common.table.MRHighlightableCellRenderer#getTreeCellRendererComponent(JTree, Object, boolean, boolean, boolean, int, boolean)
         * 这个渲染器
         */
        if(o instanceof DefaultMutableTreeTableNode){
            if(columnDesc.isColumnTree()){
                return null;
            }
        }
        return MR_TABLE_CELL_RENDERER;
    }

    /**
     * 方格对象决定是否可编辑
     * @param o
     * @return
     */
    @Override
    public boolean isCellEditable(Object o) {
        return cellEditable;
    }

    /**
     * 当可编辑时，点击方格时，编辑器
     * @param o 一行对象，而本身是一个列对象，肯定有key,此时就可以获取到方格的值
     * @return
     */
    @Override
    public @Nullable TableCellEditor getEditor(Object o) {
        TreeLineWrap treeLineWrap = null;
        if(o instanceof DefaultMutableTreeTableNode){
            DefaultMutableTreeTableNode treeTableNode = (DefaultMutableTreeTableNode)o;
            Object userObject = treeTableNode.getUserObject();
            if(userObject instanceof TreeLineWrap){
                treeLineWrap = (TreeLineWrap)userObject;
            }
        }else if(o instanceof TreeLineWrap){
            treeLineWrap = (TreeLineWrap)o;
        }
        if(null == treeLineWrap){
            return defaultJsonEditorV2;
        }
        ColumnDesc columnDesc = (ColumnDesc)treeLineWrap.getCm().get(key);
//            if(ColumnValueEnum.JSON.equals(columnDesc.getColumnValueEnum())){
//                return defaultJsonEditorV2;
//            }else if(ColumnValueEnum.ESCAPE_JSON.equals(columnDesc.getColumnValueEnum())){
//                return defaultJsonEditorV2;
//            }
        if(JacksonUtils.jsonStr(columnDesc.getValueShow())){
            return defaultJsonEditorV2;
        }
        if(ColumnValueEnum.SELECT.equals(columnDesc.getColumnValueEnum())){
            if(null == createComboBoxEditor){
                createComboBoxEditor = CellEditorFactory.createComboBoxEditor(false, columnDesc.getOptions().toArray(new String[0]));
            }
            return createComboBoxEditor;
        }else if(ColumnValueEnum.CHECKBOX.equals(columnDesc.getColumnValueEnum())){
            if(null == booleanTableCellEditor){
                booleanTableCellEditor = new MREditorBooleanTableCellEditor();
            }
            return booleanTableCellEditor;
        }else if(ColumnValueEnum.SELECT_MULTI.equals(columnDesc.getColumnValueEnum())){
            if(null == cellEditorMultiSelect){
                cellEditorMultiSelect = new CellEditorMultiSelect(project);
            }
            return cellEditorMultiSelect;
        }
        return defaultEditor;
    }

    /**
     *
     * @param o TreeLineWrap
     * @param value javax.swing.CellEditor#getCellEditorValue() 从该方法返回的值
     */
    @Override
    public void setValue(Object o, Object value) {
//        System.out.println("o --> " + o);
        TreeLineWrap treeLineWrap = null;
        if(o instanceof DefaultMutableTreeTableNode){
            DefaultMutableTreeTableNode treeTableNode = (DefaultMutableTreeTableNode)o;
            Object userObject = treeTableNode.getUserObject();
            if(userObject instanceof TreeLineWrap){
                treeLineWrap = (TreeLineWrap)userObject;
            }
        }else if(o instanceof TreeLineWrap){
            treeLineWrap = (TreeLineWrap)o;
        }
        if(null != treeLineWrap){
            ColumnDesc columnDesc = (ColumnDesc)treeLineWrap.getCm().get(key);
            String newValue = columnDesc.getColumnValueEnum().transferValue(value);
            if(newValue.equals(columnDesc.getValueShow())){
                return;
            }
            columnDesc.setValueShow(newValue);
            TreeLineObject old = treeLineWrap.getT().copyThis();
            treeLineWrap.updateValueToObj(columnDesc, value, treeLineWrap.getT());
            TreeLineObject update = treeLineWrap.getT().copyThis();
            treeLineWrap.invokeVcFun(old, update, columnDesc);
        }
    }
}
